<template>
  <Card class="flex flex-col h-full">
    <div class="p-4 flex flex-col h-full">
      <!-- Filters and Search -->
      <div class="flex flex-col gap-4 mb-4 items-center flex-shrink-0">
        <!-- Search -->
        <div class="w-full max-w-sm">
          <el-input
            v-model="query"
            placeholder="搜索歌曲或歌手"
            clearable
            @keyup.enter="applyFilters"
          />
        </div>

        <!-- Style Filter -->
        <div class="flex items-center gap-4 justify-center w-full max-w-sm">
          <div class="flex items-center gap-2 flex-wrap justify-center flex-grow">
            <el-check-tag
              v-for="style in styleOptions"
              :key="style"
              :checked="selectedStyles.includes(style)"
              @change="toggleStyle(style)"
              class="custom-check-tag"
            >
              {{ style }}
            </el-check-tag>
          </div>
          <el-button
            :icon="RefreshLeft"
            circle
            @click="resetStyles"
            title="重置筛选"
          />
        </div>
        
        <div class="flex w-full max-w-sm gap-2">
          <el-button
            type="primary"
            @click="applyFilters"
            class="flex-grow"
            style="flex-basis: 66.66%"
          >
            搜索
          </el-button>
          <el-button
            @click="openBlindBox"
            class="flex-grow"
            style="flex-basis: 33.33%"
          >
            盲盒
          </el-button>
        </div>
      </div>

      <!-- Song Table -->
      <div class="flex-grow overflow-hidden" ref="tableContainer">
        <el-table
          :data="songs"
          stripe
          border
          fit
          :max-height="tableMaxHeight"
          style="width: 100%"
          @sort-change="handleSortChange"
        >
          <el-table-column prop="song_name" label="歌曲名" min-width="130" align="center" header-align="center" />
          <el-table-column prop="singer" label="原唱" min-width="100" align="center" header-align="center" sortable="custom" />
          <el-table-column label="曲风" width="120" min-width="80" align="center" header-align="center">
            <template #default="{ row }">
              <span v-if="row.styles && row.styles.length > 0">
                {{ row.styles.join('、') }}
              </span>
              <span v-else>暂无</span>
            </template>
          </el-table-column>
          <el-table-column prop="language" label="语言" min-width="80" align="center" header-align="center" sortable="custom" />
          <el-table-column prop="last_performed" label="最近一次演唱" min-width="140" align="center" header-align="center" sortable="custom" />
          <el-table-column prop="perform_count" label="演唱次数" min-width="100" align="center" header-align="center" sortable="custom" />
          <el-table-column label="演唱记录" width="120" align="center" header-align="center">
            <template #default="{ row }">
              <el-button type="primary" link @click="showRecordPopup(row)">查看</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <!-- Pagination -->
      <div class="flex justify-center mt-4 flex-shrink-0">
        <el-pagination
          v-model:current-page="curPage"
          :page-size="pageSize"
          :total="total"
          layout="prev, pager, next"
          background
        />
      </div>
    </div>
    <RecordPopup
      v-model:visible="isPopupVisible"
      :song-id="selectedSong?.id ?? null"
      :song-name="selectedSong?.song_name || ''"
      @close="selectedSong = null"
    />
  </Card>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, computed, watch, nextTick } from 'vue'
import { RefreshLeft } from '@element-plus/icons-vue'
import type { Song } from '~/types/song'
import Card from '~/components/common/Card.vue'
import RecordPopup from '~/components/singing/RecordPopup.vue'

definePageMeta({
  navTitle: '所有歌曲',
  order: 2,
})

const songs = ref<Song[]>([])
const total = ref(0)
const curPage = ref(1)
const pageSize = ref(10)
const query = ref('')
const sortField = ref<keyof Song>('perform_count')
const sortOrder = ref('desc')
const selectedStyles = ref<string[]>([])
const styleOptions = ref<string[]>([])
const tableContainer = ref<HTMLElement | null>(null)
const tableMaxHeight = ref(400) // Default max-height

// For Record Popup
const isPopupVisible = ref(false)
const selectedSong = ref<Song | null>(null)

const totalPages = computed(() => Math.ceil(total.value / pageSize.value))

function showRecordPopup(song: Song) {
  selectedSong.value = song
  isPopupVisible.value = true
}

async function openBlindBox() {
  try {
    const randomSong = await $fetch('/api/songs/random')
    if (randomSong) {
      showRecordPopup(randomSong)
    }
  } catch (error) {
    console.error('Failed to fetch random song:', error)
  }
}

async function fetchSongs() {
  const params = {
    page: curPage.value,
    limit: pageSize.value,
    q: query.value,
    styles: selectedStyles.value.join(','),
    ordering: `${sortOrder.value === 'desc' ? '-' : ''}${sortField.value}`,
  }

  const { results, total: totalSongs } = await $fetch('/api/songs', { params })
  songs.value = results
  total.value = totalSongs
}

async function fetchStyles() {
  styleOptions.value = await $fetch('/api/styles')
}

function applyFilters() {
  curPage.value = 1
  fetchSongs()
}

function handleSortChange({ prop, order }: { prop: keyof Song, order: 'ascending' | 'descending' | null }) {
  if (prop && order) {
    sortField.value = prop
    sortOrder.value = order === 'descending' ? 'desc' : 'asc'
  } else {
    sortField.value = 'perform_count'
    sortOrder.value = 'desc'
  }
  fetchSongs()
}

function toggleStyle(style: string) {
  const index = selectedStyles.value.indexOf(style)
  if (index > -1) {
    selectedStyles.value.splice(index, 1)
  } else {
    selectedStyles.value.push(style)
  }
}

function resetStyles() {
  selectedStyles.value = []
  applyFilters()
}

let resizeObserver: ResizeObserver | null = null

function updateTableLayout() {
  if (tableContainer.value) {
    const containerHeight = tableContainer.value.clientHeight
    tableMaxHeight.value = containerHeight

    const headerHeight = 44
    const rowHeight = 44
    const newPageSize = Math.floor((containerHeight - headerHeight) / rowHeight)
    
    if (newPageSize > 0 && newPageSize !== pageSize.value) {
      pageSize.value = newPageSize
    }
  }
}

watch(curPage, fetchSongs)

watch(pageSize, (newValue, oldValue) => {
  if (newValue !== oldValue) {
    curPage.value = 1
    fetchSongs()
  }
})

onMounted(async () => {
  await fetchStyles()

  nextTick(() => {
    if (tableContainer.value) {
      updateTableLayout()
      fetchSongs()
      
      resizeObserver = new ResizeObserver(updateTableLayout)
      resizeObserver.observe(tableContainer.value)
    }
  })
})

onUnmounted(() => {
  if (resizeObserver && tableContainer.value) {
    resizeObserver.unobserve(tableContainer.value)
  }
})
</script>

<style scoped>
.custom-check-tag {
  cursor: pointer;
  background-color: var(--el-fill-color-light);
  border-color: var(--el-border-color);
  color: var(--el-text-color-regular);
}

.custom-check-tag.is-checked {
  background-color: var(--el-color-primary);
  border-color: var(--el-color-primary);
  color: var(--el-color-white);
}
</style>